﻿// -------------------------------------------------------------------------------------------------------------------------------
// <copyright file="TestGetAt.cs" company="Exul">
//     Copyright (c) Exul. All rights reserved.
// </copyright>
// <author>
//     Exul
// </author>
// -------------------------------------------------------------------------------------------------------------------------------

namespace ExulLibrary.Mathematics.LinearAlgebra.Sequential.Tests.CMFlattenDenseMatrixTest
{
    #region Usings

    using System;

    using ExulLibrary.Exceptions;

    using NUnit.Framework;

    #endregion

    /// <summary>
    ///     Test suite for <see cref="CMFlattenDenseMatrixExtensions.GetAt{T}"/>.
    /// </summary>
    [TestFixture]
    [Category("ExulLibrary.Mathematics.LinearAlgebra.Sequential.CMFlattenDenseMatrixExtensions")]
    public sealed class TestGetAt
    {
        /// <summary>
        ///     Tests the method when indexes are non-negative and less than size of corresponding dimension.
        /// </summary>
        /// <param name="rowIndex">
        ///     The zero-based index of row of the element to get.
        /// </param>
        /// <param name="columnIndex">
        ///     The zero-based index of column of the element to get.
        /// </param>
        /// <param name="elementIndex">
        ///     The index of the element in the storage.
        /// </param>
        [Test]
        [TestCase(0, 0, 0)]
        [TestCase(0, 1, 2)]
        [TestCase(0, 2, 4)]
        [TestCase(1, 0, 1)]
        [TestCase(1, 1, 3)]
        [TestCase(1, 2, 5)]
        public void WhenIndexesAreValid(int rowIndex, int columnIndex, int elementIndex)
        {
            // Arrange
            var data = new[]
                       {
                           new object(), new object(),
                           new object(), new object(),
                           new object(), new object()
                       };
            var matrix = new CMFlattenDenseMatrix<object>(2, 3, data);

            // Act
            var result = matrix.GetAt(rowIndex, columnIndex);

            // Assert
            Assert.That(result, Is.SameAs(data[elementIndex]));
        }

#if SAFE

        /// <summary>
        ///     Tests the method when rowIndex parameter is negative or greater than or equal to rows count.
        /// </summary>
        /// <param name="rowIndex">
        ///     The row index of the element to get.
        /// </param>
        [Test]
        public void WhenRowIndexIsOutOfRange([Values(-1, 2)] int rowIndex)
        {
            // Arrange
            var matrix = new CMFlattenDenseMatrix<object>(2, 3);

            // Act and Assert
            Assert.That(
                () => matrix.GetAt(rowIndex, 0),
                Throws.TypeOf<ElementIndexIsOutOfRangeException>().With.Property("ParamName").EqualTo("rowIndex"));
        }

        /// <summary>
        ///     Tests the method when columnIndex parameter is negative or greater than or equal to columns count.
        /// </summary>
        /// <param name="columnIndex">
        ///     The column index of the element to get.
        /// </param>
        [Test]
        public void WhenColumnIndexIsOutOfRange([Values(-1, 3)] int columnIndex)
        {
            // Arrange
            var matrix = new CMFlattenDenseMatrix<object>(2, 3);

            // Act and Assert
            Assert.That(
                () => matrix.GetAt(0, columnIndex),
                Throws.TypeOf<ElementIndexIsOutOfRangeException>().With.Property("ParamName").EqualTo("columnIndex"));
        }

        /// <summary>
        ///     Tests the method when matrix parameter is <see langword="null"/>.
        /// </summary>
        [Test]
        public void WhenMatrixIsNull()
        {
            // Act and Assert
            Assert.That(
                () => CMFlattenDenseMatrixExtensions.GetAt<object>(null, 0, 0),
                Throws.TypeOf<ArgumentNullException>().With.Property("ParamName").EqualTo("matrix"));
        }

#endif
    }
}